package orxatas.travelme.manager;

import android.os.AsyncTask;
import orxatas.travelme.activity.AsyncActivity;
import orxatas.travelme.entity.User;
import orxatas.travelme.manager.exceptions.*;
import orxatas.travelme.sync.AsyncNoticeCode;
import orxatas.travelme.sync.SyncAccount;


/**
 * Gestor de cuenta
 * Modulo relativo a la gestión de las cuentas: inicio de sesión, etc
 * */
public class AccountManager {

	private AsyncActivity asyncActivity;
	private SyncAccount syncAccount;
	
	private int tamMinName = 3;
	private int tamMaxName = 49;
		
	public AccountManager(AsyncActivity asyncActivity){
		this.asyncActivity = asyncActivity;
		syncAccount = new SyncAccount(asyncActivity);
	}
	
	private class SyncLoginCall extends AsyncTask<Void, Void, Boolean>{
		
		private final String email;
		private final String password;
		private final int syncAction;
		
		SyncLoginCall(String email, String password, int syncAction){
			this.email = email;
			this.password = password;
			this.syncAction = syncAction;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			
			asyncActivity.syncAndWaitCallEnded(result, syncAction);
		}

		@Override
		protected void onPreExecute() {
			asyncActivity.syncAndWaitCallStarted();
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			if(syncAccount.login(email, password) == null){
				return false;
			}
			else return true;
		}
		
	}
	private class SyncRegisterCall extends AsyncTask<Void, Void, Boolean>{
		
		private final String email;
		private final String password;
		private final String userName;
		private final int syncAction;
		
		SyncRegisterCall(String email, String password,String userName, int syncAction){
			this.email = email;
			this.password = password;
			this.userName = userName;
			this.syncAction = syncAction;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			
			asyncActivity.syncAndWaitCallEnded(result, syncAction);
		}

		@Override
		protected void onPreExecute() {
			asyncActivity.syncAndWaitCallStarted();
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			return syncAccount.register(email, password, userName);
		}
	}
	
	/**
	 * Realiza la petición al servidor para comprobar la identificación del usuario. Acción síncrona.
	 * 
	 * @param email Email asociado al usuario.
	 * @param password Password del usuario.
	 * @param syncAction Action passed that identify that sync action.
	 * 
	 * @return Devuelve true si la identificación ha tenido éxito, o false en caso contrario.
	 * */
	public void login(String email, String password, int syncAction){
		
		//We create a paralel thread.
		new SyncLoginCall(email, password, syncAction).execute();
	}
	
	/**
	 * Comprueba si ya hay usuario logueado.
	 * 
	 * @return boolean True si hay un usuario logueado
	 * */
	public boolean isLogged(){
		if(syncAccount.getUserLogged()!=null)
			return true;
		else return false;
	}
	
	/**
	 * Desconecta al usuario actual
	 * */
	public void disconnect(){
		syncAccount.disconnect();
	}
	
	/**
	 * Devuelve el usuario logueado.
	 * 
	 * @return Usuario logueado, si lo hay.
	 * */
	public User getUserLogged(){
		
		return syncAccount.getUserLogged();
	}
	
	/**
	 * Devuelve el password del usuario logueado.
	 * 
	 * @return Password del usuario logueado, si lo hay.
	 * */
	public String getPassword(){
		
		return syncAccount.getPassword();
	}
	
	public void register(String email, String password, String passwordConfirmacion ,String userName , int syncAction) throws BadData,NotTheSame{
		if(password.equals(passwordConfirmacion) == true)
			if(userName.length() < tamMaxName  || userName.length() >= tamMinName )
				new SyncRegisterCall(email, passwordConfirmacion, userName, syncAction).execute();
			else 
				throw new BadData();
		else 
			throw new NotTheSame();
	}
	
	/**
	 * Se le avisa de que hay una sincronización en curso. Convenio: Sólo utilizar cuando por su clase de sincronización.
	 * */
	public void syncInProgress(){

		asyncActivity.syncStarted();
	}
	
	/**
	 * Se le avisa de que la sincronización en curso ha terminado. Convenio: Sólo utilizar cuando por su clase de sincronización.
	 * */
	public void syncInProgressEnd(){
		
		asyncActivity.syncEnded();
	}
	/**
	 * Evento asyncrono para cambios en los grupos.
	 * */
	public void asyncNotice(AsyncNoticeCode code){
		
		asyncActivity.asyncNotice(code);
	}
}
